package org.adream.account.service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpSession;

import org.adream.account.dao.RealNameAuthDao;
import org.adream.account.dao.RealNameTmpDao;
import org.adream.account.dao.UserDao;
import org.adream.account.dao.UserRoleLinkDao;
import org.adream.account.dao.UserVerifyDao;
import org.adream.account.entity.RealNameAuthEntity;
import org.adream.account.entity.RealNameTmpEntity;
import org.adream.account.entity.UserEntity;
import org.adream.account.entity.UserVerifyEntity;
import org.adream.account.model.ResultModel;
import org.adream.account.model.SynDream2020DataModel;
import org.adream.account.rest.api.model.DataTableRequest;
import org.adream.account.service.async.SynDream2020Service;
import org.adream.account.util.Constant;
import org.adream.account.util.SensorDataUtil;
import org.adream.account.util.Utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

@Service
public class RealNameAuthService {
	
	private final static Logger logger = LoggerFactory.getLogger(RealNameAuthService.class);
	
	@Autowired
	private RealNameAuthDao authDao;
	
	@Autowired
	private UserRoleLinkDao userRoleDao;
	
	@Autowired
	private HttpSession session;
	
	@Autowired
	private UserDao userDao;
	
	@Autowired
	private UserVerifyDao verifyDao;
	
	@Autowired
	private RealNameTmpDao tmpDao;
	
	@Autowired
	private SynDream2020Service synDream2020Service;
	
	@Autowired
	private UserVerifyService userVerifyService;
	
	@Autowired
	private SensorDataUtil sensorDataUtil;
	
	@Autowired
	private UserRoleLinkDao userRoleLinkDao;

	/**
	 * 注意 此处的实名ADD   会覆盖身份认证中间表 
	 * @param realNameAuth
	 */
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, isolation = Isolation.DEFAULT)
	public boolean addRealNameAuth(RealNameAuthEntity realNameAuth) {
		realNameAuth.setCreator((String) session.getAttribute("uid"));
		realNameAuth.setCts(new Date());
		realNameAuth.setModifier((String) session.getAttribute("uid"));
		realNameAuth.setMts(new Date());
		realNameAuth.setDr(Constant.ONE);
		if (authDao.addRealNameAuth(realNameAuth)!=1) {
		  //插入数据库失败
			return false;
		}
		//实名认证通过 状态为2的  覆盖身份中间表
//		List<UserVerifyEntity> verifies = verifyDao.queryVerifiesByUidAndDr(realNameAuth.getUid(),Constant.ONE);
//		if(verifies == null || verifies.size() == Constant.ZERO) {
		//if(realNameAuth.getState()!=null && realNameAuth.getState() == 2) {
		RealNameTmpEntity realNameTmp = new RealNameTmpEntity();
		Utils.copyPropertiesIgnoreNull(realNameAuth, realNameTmp);
		tmpDao.replaceRealNameTmp(realNameTmp);
		//}
		return true;
	}
	
	/**
	 * 删 逻辑删
	 * @param uid user id
	 */
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, isolation = Isolation.DEFAULT)
	public ResultModel<String> deleteRealNameAuth(String uid) {
		RealNameAuthEntity realNameAuth = authDao.queryAuthByUidAndDr(uid, Constant.ONE);
		if(realNameAuth == null) {
			return new ResultModel<String>(ResultModel.NOT_FOUND_OBJECT, "删除失败,数据不存在", null);
		}
		realNameAuth.setModifier((String) session.getAttribute("uid"));
		realNameAuth.setMts(new Date());
		realNameAuth.setDr(Constant.ZERO);
		int result = authDao.deleteRealNameAuth(realNameAuth);
		if(result == 0) {
			return new ResultModel<String>(ResultModel.ERR_DATABASE, "系统错误,请联系系统管理员", null);
		}
		//删除用户实名角色
		userRoleDao.deleteUserRole(uid, Constant.REALNAME_ROLE_ID);
		return new ResultModel<String>(ResultModel.SUCCESS, ResultModel.SUCCESS_MSG, null);
	}
	
	/**
	 * 注意：此处的UPDATE  会覆盖身份中间表
	 * @param realNameAuth
	 */
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, isolation = Isolation.DEFAULT)
	public boolean updateRealNameAuth(RealNameAuthEntity realNameAuth) {
		realNameAuth.setModifier((String) session.getAttribute("uid"));
		realNameAuth.setMts(new Date());
		realNameAuth.setVerifySuccessts(null);
		if(authDao.updateRealNameAuth(realNameAuth)!=1) {
			return false;
		}
		
//		List<UserVerifyEntity> verifies = verifyDao.queryVerifiesByUidAndDr(realNameAuth.getUid(),Constant.ONE);
//		if(verifies == null || verifies.size() == Constant.ZERO) {
		// 覆盖身份中间表

		RealNameTmpEntity realNameTmp = new RealNameTmpEntity();
		Utils.copyPropertiesIgnoreNull(realNameAuth, realNameTmp);
		tmpDao.replaceRealNameTmp(realNameTmp);
		 
		return true;
	}
	
	/**
	 * 审核"实名认证"并同步数据
	 * @param realNameAuthEntity
	 * @return
	 */
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = ADreamServiceException.class, isolation = Isolation.DEFAULT)
	public ResultModel<?> checkAuthAndSynData(RealNameAuthEntity realNameAuthEntity) {
		RealNameAuthEntity realNameAuth = authDao.queryAuthByUidAndDr(realNameAuthEntity.getUid(), Constant.ONE);
		if (realNameAuth == null) {
			logger.warn("审核失败,相关数据未存在:(");
			return new ResultModel<String>(ResultModel.NOT_FOUND_OBJECT, "审核失败,数据未存在", null);
		}
		String uid = realNameAuthEntity.getUid();

		Map<String, Object> properties = new HashMap<>();
		properties.put("document_type", realNameAuth.getCreType() == Constant.ZERO ? "身份证" : "护照");
		properties.put("is_audit", false);
		//管理端调用时,modifier从session中获取
		//ocr识别自动审核调用时,不能获取request,将报No thread-bound request found错误
		String modifier = null;
		try {
			modifier = (String) session.getAttribute("uid");
		} catch (Exception e) {
			modifier = realNameAuthEntity.getUid();
		}
		realNameAuthEntity.setModifier(modifier);
		
		realNameAuthEntity.setMts(new Date());
		Utils.copyPropertiesIgnoreNull(realNameAuthEntity, realNameAuth);
		
		//更新用户
		UserEntity user = userDao.queryUserByUid(realNameAuth.getUid());
		
		SynDream2020DataModel data = new SynDream2020DataModel();
		data.setCasid(realNameAuth.getUid());
		
		//修改用户实名角色
		//实名认证通过,添加用户实名角色
		if(realNameAuth.getState() == Constant.TWO) {
			realNameAuth.setVerifySuccessts(new Date());
			
			userRoleDao.replaceUserRoleById(realNameAuth.getUid(), Constant.REALNAME_ROLE_ID);
			
			if(user != null) {
				user.setRealName(realNameAuth.getRealName());
				user.setVerified(Constant.VERIFIED);
				
				data.setRealname(realNameAuth.getRealName());
				data.setVerified(Constant.VERIFIED);
				//神策数据设置用户属性
				SensorDataUtil.saProfileSet(realNameAuth.getUid(), true, "name", realNameAuth.getRealName());
				SensorDataUtil.saProfileSet(realNameAuth.getUid(), true, "role_name", userRoleLinkDao.queryRolesByUidAndDr(realNameAuth.getUid(), Constant.ONE) != null ?
					userRoleLinkDao.queryRolesByUidAndDr(realNameAuth.getUid(), Constant.ONE).getRleName() : "");
			}
			//处理梦想教师 身份认证 通过
			try {
				UserVerifyEntity teacherVerifyEntity = verifyDao.queryVerifyByUidAndRleId(realNameAuth.getUid(),Constant.TEACHER_ROLE_ID);
				if(teacherVerifyEntity!=null 
						&& teacherVerifyEntity.getState()!=null 
						&& teacherVerifyEntity.getState() !=2) {
					teacherVerifyEntity.setState(2);
					teacherVerifyEntity.setCheckResult("身份认证通过");
					teacherVerifyEntity.setAutoCheckResult("实名认证已通过，身份实名通过");
					//若进行了身份认证审核操作,需埋点'盒子_身份认证审核结果'事件,直接在身份认证审核进行埋点
					userVerifyService.checkVerifyAndSynData("auto", teacherVerifyEntity.getUid(),
							teacherVerifyEntity.getRleId(), teacherVerifyEntity);
				}
			} catch (Exception e) {
				logger.warn("实名通过以后,处理身份认证错误");
			}
//			List<UserVerifyEntity> verifies = verifyDao.queryVerifiesByUidAndDr(realNameAuth.getUid(),Constant.ONE);
//			if(verifies == null || verifies.size() == Constant.ZERO) {
			//通过状态的直接覆盖之间表
			RealNameTmpEntity realNameTmp = new RealNameTmpEntity();
			Utils.copyPropertiesIgnoreNull(realNameAuth, realNameTmp);
			tmpDao.replaceRealNameTmp(realNameTmp);
//			}			
			//神策数据设置用户属性 '姓名'
			SensorDataUtil.saProfileSet(realNameAuth.getUid(), true, "name", realNameAuth.getRealName());

		} else {
			realNameAuth.setVerifySuccessts(null);
			
			//认证未通过,删除用户实名角色
			userRoleDao.deleteUserRole(realNameAuth.getUid(), Constant.REALNAME_ROLE_ID);
			
			if(user != null) {
				user.setRealName(null);
				user.setVerified(Constant.NOTVERIFIED);
				
				data.setRealname("");
				data.setVerified(Constant.NOTVERIFIED);
			}
		}
		int result = authDao.checkAuth(realNameAuth);
		if(result == Constant.ZERO) {
			logger.warn("审核失败,内部出错:(");
			properties.put("failure_reason", "系统原因");
			SensorDataUtil.saTrack(uid, true, Constant.SENSOR_DATA_ADREAMBOX_IDCARD_RESULT, properties);	
			return new ResultModel<String>(ResultModel.ERR_DATABASE, "审核失败,请联系管理员", null);			
		}
		
		if(user != null) {
			try {
				user.setModifier((String) session.getAttribute("uid"));
			} catch (Exception e) {
				user.setModifier(realNameAuthEntity.getUid());
			}
			
			user.setMts(new Date());
			userDao.updateRealName(user);
			synDream2020Service.synDream2020Data(data);
		}
		//不为'审核中'的
		if(realNameAuth.getState() != null && realNameAuth.getState() != Constant.ONE) {
			properties.put("is_audit", realNameAuth.getState() == Constant.TWO ? true : false);
			properties.put("failure_reason", realNameAuth.getState() == Constant.TWO ? "" : realNameAuth.getCheckResult());
			//神策数据设置用户属性 '姓名'
			SensorDataUtil.saTrack(uid, true, Constant.SENSOR_DATA_ADREAMBOX_IDCARD_RESULT, properties);
			
		}
		return new ResultModel<String>(ResultModel.SUCCESS, ResultModel.SUCCESS_MSG, null);
	}
	
	/**
	 * 根据删除标志查询实名认证
	 * @param dr	删除标志
	 * @return
	 */
	public List<RealNameAuthEntity> queryRealNameAuthsByDr(Integer dr) {
		return authDao.queryRealNameAuthsByDr(dr);
	}
	
	/**
	 * 根据uid和删除标志查询实名认证
	 * @param uid user id
	 * @param dr  删除标志
	 * @return
	 */
	public RealNameAuthEntity queryAuthByUidAndDr(String uid,Integer dr) {
		return authDao.queryAuthByUidAndDr(uid, dr);
	}
	
	/**
	 * 根据uid查询实名认证
	 * @param uid user id
	 * @return
	 */
	public RealNameAuthEntity queryAuthByUid(String uid) {
		return authDao.queryAuthByUid(uid);
	}
	
	/**
	 * 分页查询
	 * @param dr
	 * @param pageNo
	 * @param pageSize
	 * @return
	 */
	public PageInfo<RealNameAuthEntity> selectPageAuth(String uid, String realName,Integer creType,Integer state,
			Integer dr,Integer pageNo,Integer pageSize) {
		pageNo = (pageNo == null) ? Constant.ONE : pageNo;
		pageSize = (pageSize == null) ? Constant.TEN : pageSize;
		PageHelper.startPage(pageNo,pageSize);
		List<RealNameAuthEntity> auths = authDao.queryAuthsBySomeFields(uid, realName, creType, state, dr);
		PageInfo<RealNameAuthEntity> page = new PageInfo<>(auths,Constant.TEN);
		return page;
	}
	/**
	 * 处理实名信息是否被占用
	 * @param realNameAuthEntity
	 * @return
	 */
	public String vaildateIdCard(String uid,String creNum) {
		if(StringUtils.isEmpty(uid)||StringUtils.isEmpty(creNum)) {
			return null;
		}
		//身份证号被哪些用户占用
		ArrayList<Map<String, String>> list = authDao.selectByCreNum(uid,creNum);
		
		if(list==null||list.size()==0) {
//			realNameAuthEntity.setState(Constant.ONE);
//			realNameAuthEntity.setCheckResult("正在审核中,请耐心等候");
			return null;
		}else {
			//处理字符串
			String msg = "其他用户";
			
			Map<String, String> info = list.get(0);
			String uname = info.get("uname");
			String phone = info.get("phone");
			String email = info.get("email");

			if (!StringUtils.isEmpty(email)) {
				msg = "邮箱为\"" + email.replaceAll("(\\w{3})(\\w*)(@\\w+\\.[a-z]+(\\.[a-z]+)?)", "$1****$3") + "\"的用户";
			} else if (!StringUtils.isEmpty(phone)) {
				msg = "手机号为\"" + Utils.replaceXing(phone, 3, 4) + "\"的用户";
			} else if (!StringUtils.isEmpty(uname)) {
				msg = "昵称为\"" + uname.trim() + "\"的用户";
			}
			msg =   "身份证已被"+msg+"使用";
//			realNameAuthEntity.setState(Constant.THREE);
//			realNameAuthEntity.setCheckResult("身份证已被"+msg+"使用");
			return msg;
		}

//		return realNameAuthEntity;
	}

	public PageInfo<RealNameAuthEntity> queryAuthByDataTable(DataTableRequest dtr) {
		PageHelper.startPage(dtr.getStart()/dtr.getLength()+1, dtr.getLength());
		List<RealNameAuthEntity> oel= authDao.queryAuthByDataTable(dtr);
		PageInfo<RealNameAuthEntity> oelp = new PageInfo<>(oel);
		return oelp;
	}
}